package mx.com.crowdgine.display.animation.mocap;

import java.io.IOException;

import com.jogamp.common.nio.Buffers;

import mx.com.crowdgine.assetloader.TextureReader;
import mx.com.crowdgine.assetloader.TextureRectangle;
import mx.com.crowdgine.display.animation.AnimationFrame;
import mx.com.crowdgine.display.animation.glsl.GLSLAnimation;
import mx.com.crowdgine.display.animation.skinning.ImageBasedSkinningEncoder;

public class MocapAnimation extends GLSLAnimation {

	private String asfFilePath;
	private String amcFilePath;
	private String objFilePath;
	private String jointImageFilePath;
	private String meshTextureFilePath;
	
	private ImageBasedSkinningEncoder skinningEncoder;
	private MocapTextureEncoder mocapTextureEncoder;
	
	public MocapAnimation(String asfFilePath, String amcFilePath, String objFilePath, String jointImageFilePath, String vertexShaderFilePath, String fragmentShaderFilePath, String meshTextureFilePath) {
		super(vertexShaderFilePath, fragmentShaderFilePath);
		
		this.asfFilePath = asfFilePath;
		this.amcFilePath = amcFilePath;
		this.objFilePath = objFilePath;
		this.jointImageFilePath = jointImageFilePath;
		this.meshTextureFilePath = meshTextureFilePath;
		
		skinningEncoder = new ImageBasedSkinningEncoder(this.objFilePath, this.jointImageFilePath);
		
		mocapTextureEncoder = new MocapTextureEncoder();
		mocapTextureEncoder.setAsfFile(new ASFFile(this.asfFilePath));
		mocapTextureEncoder.addAmcFile(new AMCFile(this.amcFilePath));
		
		
		float [] rootData = mocapTextureEncoder.encodeRootData();
		this.setParameter("rootData", Buffers.newDirectFloatBuffer(rootData), 4, rootData.length);
//		printArray("rootData", rootData, 4);
		this.setDynamicParameter("<ROOT_DATA_SIZE>", rootData.length / 4);
		
		float [] boneData = mocapTextureEncoder.encodeBoneData();
		this.setParameter("boneData", Buffers.newDirectFloatBuffer(boneData), 4, boneData.length);
//		printArray("boneData", boneData, 4);
		this.setDynamicParameter("<BONE_DATA_SIZE>", boneData.length / 4);
		
		float [] jointData = skinningEncoder.getJointData();
		this.setParameter("jointList", Buffers.newDirectFloatBuffer(jointData), 3, jointData.length);
//		printArray("jointList", jointData, 3);
		this.setDynamicParameter("<JOINT_LIST_SIZE>", jointData.length / 3);
		
		try {
			this.setParameter("meshTexture", TextureReader.readTexture(this.meshTextureFilePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		AnimationFrame frame = null;
		float [] animationData = null;
		for(int f = 0; f < mocapTextureEncoder.getNumFrames(); f++) {
			frame = new AnimationFrame();
			animationData = mocapTextureEncoder.encodeFrame(f, 0, 0);
			
			frame.setData(Buffers.newDirectFloatBuffer(animationData));
			frame.setDataLength(animationData.length);
			frame.setDataSize(4);
			
			this.getFrames().add(frame);
		}
		
		if(this.getFrames().size() > 0)
			this.setDynamicParameter("<ANIMATION_DATA_SIZE>", this.getFrames().get(0).getDataLength() / 4);
		else
			this.setDynamicParameter("<ANIMATION_DATA_SIZE>",50);
		
	}
	
	
	private void printArray(String name, float [] data, int size) {
		System.out.println("----------------------------------------------------");
		for(int i = 0; i < data.length/size; i++) {
			System.out.print(name + "["+i+"]: (");
			for(int j = 0; j < size; j++) {
				if(j != 0) {
					System.out.print(", ");
				}
				System.out.print(data[size*i+j]);
			}
			System.out.println(")");
		}
		System.out.println("----------------------------------------------------");
	}
	
	
}
